package com.jprocms.module.cms.controller.directive;

import cn.hutool.core.util.StrUtil;
import com.jprocms.module.cms.framework.util.StrUtils;
import com.jprocms.module.cms.util.Freemarkers;
import com.jprocms.module.cms.web.Directives;
import com.jprocms.module.cms.web.IUrl;
import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
import org.apache.commons.lang3.StringUtils;
import org.springframework.lang.Nullable;
import org.springframework.web.util.HtmlUtils;

import java.io.IOException;
import java.util.Map;
import java.util.Optional;

/**
 * 自定义链接标签。用于生成 html a 标签 （内容、栏目 url）
 *
 * @author jprocms
 */
public class UrlDirective implements TemplateDirectiveModel {
    public static final String OBJECT = "object";
    public static final String TARGET = "target";
    public static final String TITLE = "title";
    public static final String LENGTH = "length";
    public static final String APPEND = "append";

    @SuppressWarnings("unchecked")
    @Override
    public void execute(Environment env, Map params, TemplateModel[] loopVars,
                        @Nullable TemplateDirectiveBody body) throws TemplateException, IOException {
        IUrl url = Freemarkers.getObject(params, OBJECT, IUrl.class);
        if (url == null) {
            return;
        }

        String target = Directives.getString(params, TARGET);
        if (StrUtil.isBlank(target) && url.getTargetBlank()) {
            target = "_blank";
        }
        String title = Optional.ofNullable(Directives.getString(params, TITLE)).filter(StringUtils::isNotBlank)
                .orElseGet(url::getName);

        String append = Optional.ofNullable(Directives.getString(params, APPEND)).orElse("...");
        Integer length = Directives.getInteger(params, LENGTH);

        StringBuilder buff = new StringBuilder();
        //可能存在脏数据，url不能为空
        if(StringUtils.isNotBlank(url.getUrl())){
            buff.append("<a href=\"").append(HtmlUtils.htmlEscape(url.getUrl())).append("\"");
            buff.append(" title=\"").append(HtmlUtils.htmlEscape(title)).append("\"");
            if (StringUtils.isNotBlank(target)) {
                buff.append(" target=\"").append(HtmlUtils.htmlEscape(target)).append("\"");
            }
            // 插入其它属性
            for (Object obj : params.entrySet()) {
                Map.Entry<String, TemplateModel> entry = (Map.Entry<String, TemplateModel>) obj;
                String name = entry.getKey();
                if (StringUtils.equalsAnyIgnoreCase(name, OBJECT, TARGET, TITLE, LENGTH, APPEND)) {
                    continue;
                }
                String value = Optional.ofNullable(Freemarkers.getString(entry.getValue())).map(HtmlUtils::htmlEscape)
                        .orElse("");
                buff.append(" ").append(name).append("=\"").append(value).append("\"");
            }
            buff.append(">");
            env.getOut().write(buff.toString());
            if (body == null) {
                String innerTitle = url.getName();
                if (length != null && length > 0) {
                    innerTitle = StrUtils.substring(innerTitle, length, append);
                }
                env.getOut().write(HtmlUtils.htmlEscape(innerTitle));
            } else {
                body.render(env.getOut());
            }
            env.getOut().write("</a>");
        }
    }
}
